import React, { useState, useEffect, useMemo } from 'react';
import { Table, Input, Button, Space, Dropdown, Tag, Modal, message, DatePicker, Select, InputNumber, Row, Col, Switch } from 'antd';
import type { TableProps as AntTableProps } from 'antd';
import {
  SearchOutlined,
  ReloadOutlined,
  ExportOutlined,
  SettingOutlined,
  FileExcelOutlined,
  FilePdfOutlined,
  FileTextOutlined,
  CaretRightOutlined,
  CaretDownOutlined,
} from '@ant-design/icons';
import type { TreeTableProps, TreeTableNode, TreeTableState } from './types';

const { Option } = Select;

const TreeTable = <T extends Record<string, unknown>>(props: TreeTableProps<T>) => {
  const {
    columns,
    data,
    loading = false,
    rowKey = 'id',
    pagination,
    size = 'middle',
    showHeader = true,
    scroll,
    title,
    footer,
    searchFields = [],
    onSearch,
    onExport,
    batchActions = [],
    nodeActions = [],
    defaultExpandAll = false,
    defaultExpandedKeys = [],
    indentSize = 20,
    showExpandColumn = true,
    refresh,
    extra,
    rowClassName,
    onRow,
    onChange,
    onExpand,
    onExpandedRowsChange,
    columnSettings,
    columnPinning,
  } = props;

  // 初始化展开状态
  const getInitialExpandedKeys = () => {
    // 如果有外部控制的 expandedRowKeys，优先使用外部状态
    if (props.expandedRowKeys) {
      return props.expandedRowKeys;
    }
    // 否则使用默认展开逻辑
    return defaultExpandAll ? getAllKeys(data) : defaultExpandedKeys;
  };

  const [state, setState] = useState<TreeTableState>({
    searchText: '',
    searchParams: {},
    filteredInfo: {},
    sortedInfo: {},
    selectedRowKeys: [],
    selectedRows: [],
    visibleColumns: columnSettings?.defaultVisibleColumns || columns.map(col => col.key),
    columnSettingsVisible: false,
    pinnedColumns: columnPinning?.defaultPinnedColumns || { left: [], right: [] },
    columnPinningVisible: false,
    expandedRowKeys: getInitialExpandedKeys(),
  });

  // 展开状态优先使用外部控制
  const expandedRowKeys = props.expandedRowKeys !== undefined ? props.expandedRowKeys : state.expandedRowKeys;

  // 如果有外部控制，完全禁用内部状态管理
  const isExternallyControlled = props.expandedRowKeys !== undefined;
  

  function getAllKeys(nodes: TreeTableNode<T>[]): (string | number)[] {
    const keys: (string | number)[] = [];

    function traverse(items: TreeTableNode<T>[]) {
      items.forEach(item => {
        keys.push(item.id);
        if (item.children && item.children.length > 0) {
          traverse(item.children);
        }
      });
    }

    traverse(nodes);
    return keys;
  }

  function flattenData(nodes: TreeTableNode<T>[], level = 0, parentId?: string | number): T[] {
    const result: T[] = [];
    const processedIds = new Set<string | number>();

    function processNode(node: TreeTableNode<T>, currentLevel: number, currentParentId?: string | number) {
      // 检查节点ID是否有效
      if (!node.id || node.id === undefined || node.id === null) {
        return;
      }

      // 检查是否已经处理过这个节点
      if (processedIds.has(node.id)) {
        return;
      }

      processedIds.add(node.id);
      const hasChildren = node.children && node.children.length > 0;

      // 创建扁平节点，确保不包含循环引用
      const flatNode = {
        ...node,
        level: currentLevel,
        parentId: currentParentId,
        hasChildren,
      };

      // 删除可能造成循环引用的属性
      const cleanNode = { ...flatNode };
      delete (cleanNode as Record<string, any>).children;

      result.push(cleanNode as unknown as T);

      // 只有在节点展开且有子节点时才处理子节点
      // 使用松散比较确保类型兼容
      const nodeIdStr = String(node.id);
      const isExpanded = expandedRowKeys.some(key => String(key) === nodeIdStr);
      
      if (hasChildren && isExpanded && node.children) {
        node.children.forEach(child => {
          if (child && child.id !== node.id) { // 防止自引用
            processNode(child, currentLevel + 1, node.id);
          }
        });
      }
    }

    // 验证输入数据
    if (!Array.isArray(nodes)) {
      return [];
    }

    nodes.forEach(node => {
      if (node) {
        processNode(node, level, parentId);
      }
    });

    // 最终验证：确保结果中没有重复ID
    const finalIds = new Set<string | number>();
    const finalResult: T[] = [];

    result.forEach((item) => {
      const id = (item as Record<string, any>).id;
      if (id !== undefined && id !== null && !finalIds.has(id)) {
        finalIds.add(id);
        finalResult.push(item);
      }
    });

    return finalResult;
  }

  const flattenedData = useMemo(() => {
    return flattenData(data);
  }, [data, expandedRowKeys]);  // 使用合并后的 expandedRowKeys 而不是 state.expandedRowKeys

  // 监听外部 expandedRowKeys 的变化并同步到内部状态
  useEffect(() => {
    // 如果是外部控制且值有变化，同步到内部状态
    if (isExternallyControlled && props.expandedRowKeys !== undefined) {
      setState(prev => {
        // 只在值真的改变时才更新
        if (JSON.stringify(prev.expandedRowKeys) !== JSON.stringify(props.expandedRowKeys)) {
          return {
            ...prev,
            expandedRowKeys: props.expandedRowKeys as (string | number)[]  // 类型断言
          };
        }
        return prev;
      });
    } else if (defaultExpandAll && !isExternallyControlled) {
      setState(prev => ({
        ...prev,
        expandedRowKeys: getAllKeys(data)
      }));
    }
  }, [props.expandedRowKeys, data, defaultExpandAll, isExternallyControlled]);

  const handleSearch = (searchParams: Record<string, unknown>) => {
    setState(prev => ({
      ...prev,
      searchParams: { ...prev.searchParams, ...searchParams },
    }));
    onSearch?.({ ...state.searchParams, ...searchParams });
  };

  const handleResetSearch = () => {
    setState(prev => ({
      ...prev,
      searchText: '',
      searchParams: {},
      filteredInfo: {},
    }));
    onSearch?.({});
  };

  const handleTableChange: AntTableProps['onChange'] = (paginationConfig, filters, sorter) => {
    setState(prev => ({
      ...prev,
      filteredInfo: filters,
      sortedInfo: sorter,
    }));

    if (onChange && paginationConfig) {
      onChange(paginationConfig, filters, sorter as any);
    }
  };

  const handleRowSelection = (selectedRowKeys: React.Key[], selectedRows: T[]) => {
    setState(prev => ({
      ...prev,
      selectedRowKeys,
      selectedRows: selectedRows as unknown as TreeTableNode<Record<string, unknown>>[],
    }));
  };

  const handleExport = (format: 'csv' | 'excel' | 'pdf') => {
    onExport?.(format);
    message.success(`正在导出 ${format.toUpperCase()} 格式数据...`);
  };

  const handleColumnSettings = (visibleColumns: string[]) => {
    setState(prev => ({
      ...prev,
      visibleColumns,
    }));
    columnSettings?.onColumnsChange?.(visibleColumns);
  };


  const handleExpand = (expanded: boolean, record: T) => {
    // 获取记录ID
    const recordId = (record as Record<string, any>).id;
    
    // 计算新的展开键数组
    const newExpandedRowKeys = expanded
      ? [...expandedRowKeys, recordId]
      : expandedRowKeys.filter(key => String(key) !== String(recordId));

    // 如果是外部控制，调用外部回调来更新状态
    if (isExternallyControlled) {
      // 调用外部的状态更新函数
      onExpandedRowsChange?.(newExpandedRowKeys);
      // 也调用onExpand回调
      onExpand?.(expanded, record);
    } else {
      // 内部控制模式，更新内部状态
      setState(prev => ({
        ...prev,
        expandedRowKeys: newExpandedRowKeys,
      }));
      
      // 调用回调
      onExpand?.(expanded, record);
      onExpandedRowsChange?.(newExpandedRowKeys);
    }
  };

  const expandAll = () => {
    const allKeys = getAllKeys(data);
    setState(prev => ({
      ...prev,
      expandedRowKeys: allKeys,
    }));
    onExpandedRowsChange?.(allKeys);
  };

  const collapseAll = () => {
    setState(prev => ({
      ...prev,
      expandedRowKeys: [],
    }));
    onExpandedRowsChange?.([]);
  };

  const renderToolbar = () => {
    const menuItems = [
      {
        key: 'csv',
        label: (
          <span onClick={() => handleExport('csv')}>
            <FileTextOutlined /> 导出 CSV
          </span>
        ),
      },
      {
        key: 'excel',
        label: (
          <span onClick={() => handleExport('excel')}>
            <FileExcelOutlined /> 导出 Excel
          </span>
        ),
      },
      {
        key: 'pdf',
        label: (
          <span onClick={() => handleExport('pdf')}>
            <FilePdfOutlined /> 导出 PDF
          </span>
        ),
      },
    ];

    const settingsMenuItems = [
      {
        key: 'expandAll',
        label: (
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', width: 160 }}>
            <span>展开全部</span>
            <Button
              type="text"
              size="small"
              onClick={expandAll}
            >
              展开
            </Button>
          </div>
        ),
      },
      {
        key: 'collapseAll',
        label: (
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', width: 160 }}>
            <span>折叠全部</span>
            <Button
              type="text"
              size="small"
              onClick={collapseAll}
            >
              折叠
            </Button>
          </div>
        ),
      },
      {
        key: 'columnSettings',
        label: (
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', width: 160 }}>
            <span>显示列</span>
            <Button
              type="text"
              size="small"
              icon={<SettingOutlined />}
              onClick={() => setState(prev => ({ ...prev, columnSettingsVisible: true }))}
            />
          </div>
        ),
      },
    ];

    return (
      <div style={{ padding: '16px 20px', background: '#fff' }}>
        {searchFields.length > 0 && (
          <div style={{
            marginBottom: 16,
            padding: '16px',
            background: '#fafafa',
            borderRadius: '6px',
            border: '1px solid #f0f0f0'
          }}>
            <div style={{
              fontSize: '14px',
              fontWeight: 500,
              color: '#262626',
              marginBottom: '12px',
              display: 'flex',
              alignItems: 'center',
              gap: '6px'
            }}>
              <SearchOutlined style={{ color: '#1890ff' }} />
              搜索条件
            </div>
            <Row gutter={[16, 12]} align="middle">
              {searchFields.slice(0, 4).map(field => (
                <Col key={field.key}>
                  <Space direction="vertical" size={4}>
                    <span style={{
                      fontSize: '13px',
                      color: '#595959',
                      fontWeight: 500
                    }}>
                      {field.label}
                    </span>
                    {field.type === 'input' && (
                      <Input
                        placeholder={field.placeholder || `请输入${field.label}`}
                        allowClear={field.allowClear ?? true}
                        onChange={(e) => handleSearch({ [field.key]: e.target.value })}
                        style={{ width: 160 }}
                      />
                    )}
                    {field.type === 'select' && field.options && (
                      <Select
                        placeholder={field.placeholder || `请选择${field.label}`}
                        allowClear={field.allowClear ?? true}
                        style={{ width: 160 }}
                        onChange={(value) => handleSearch({ [field.key]: value })}
                      >
                        {field.options.map(option => (
                          <Option key={option.value} value={option.value}>
                            {option.label}
                          </Option>
                        ))}
                      </Select>
                    )}
                    {field.type === 'date' && (
                      <DatePicker
                        placeholder={field.placeholder || `请选择${field.label}`}
                        style={{ width: 180 }}
                        onChange={(date, dateString) => handleSearch({ [field.key]: dateString })}
                      />
                    )}
                    {field.type === 'number' && (
                      <InputNumber
                        placeholder={field.placeholder || `请输入${field.label}`}
                        style={{ width: 140 }}
                        onChange={(value) => handleSearch({ [field.key]: value })}
                      />
                    )}
                  </Space>
                </Col>
              ))}
              <Col>
                <div style={{ marginTop: '19px' }}>
                  <Space size={8}>
                    <Button
                      type="primary"
                      icon={<SearchOutlined />}
                      onClick={() => onSearch?.(state.searchParams)}
                    >
                      搜索
                    </Button>
                    <Button
                      icon={<ReloadOutlined />}
                      onClick={handleResetSearch}
                    >
                      重置
                    </Button>
                  </Space>
                </div>
              </Col>
            </Row>
          </div>
        )}

        {batchActions.length > 0 && state.selectedRowKeys.length > 0 && (
          <div style={{
            marginBottom: 16,
            padding: '12px 16px',
            background: '#e6f7ff',
            borderRadius: '6px',
            border: '1px solid #91d5ff'
          }}>
            <Space align="center" wrap>
              <Tag color="blue" style={{ fontWeight: 500 }}>
                已选择 {state.selectedRowKeys.length} 项
              </Tag>
              {batchActions.map(action => (
                <Button
                  key={action.key}
                  type={action.danger ? 'primary' : 'default'}
                  danger={action.danger}
                  icon={action.icon}
                  size="small"
                  onClick={() => action.onClick && action.onClick(state.selectedRows as unknown as T)}
                >
                  {action.label}
                </Button>
              ))}
              <Button
                size="small"
                onClick={() => handleRowSelection([], [])}
              >
                取消选择
              </Button>
            </Space>
          </div>
        )}

        <div style={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          paddingTop: searchFields.length > 0 || (batchActions.length > 0 && state.selectedRowKeys.length > 0) ? 0 : 0
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
            {title && (
              <div style={{
                fontSize: '16px',
                fontWeight: 600,
                color: '#262626'
              }}>
                {title()}
              </div>
            )}
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              {extra}
            </div>
          </div>

          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            {refresh && (
              <Button
                icon={<ReloadOutlined />}
                onClick={refresh}
              >
                刷新
              </Button>
            )}

            {(columnSettings?.enabled) && (
              <Dropdown menu={{ items: settingsMenuItems }} placement="bottomRight" trigger={['click']}>
                <Button
                  icon={<SettingOutlined />}
                >
                  设置
                </Button>
              </Dropdown>
            )}

            {onExport && (
              <Dropdown menu={{ items: menuItems }} placement="bottomRight">
                <Button
                  icon={<ExportOutlined />}
                >
                  导出
                </Button>
              </Dropdown>
            )}
          </div>
        </div>
      </div>
    );
  };

  const renderColumnSettings = () => {
    return (
      <Modal
        title="列显示设置"
        open={state.columnSettingsVisible}
        onCancel={() => setState(prev => ({ ...prev, columnSettingsVisible: false }))}
        footer={[
          <Button
            key="reset"
            onClick={() => {
              const allColumnKeys = columns.map(col => col.key);
              handleColumnSettings(allColumnKeys);
            }}
          >
            全部显示
          </Button>,
          <Button
            key="close"
            type="primary"
            onClick={() => setState(prev => ({ ...prev, columnSettingsVisible: false }))}
          >
            确定
          </Button>
        ]}
        width={600}
      >
        <div style={{ maxHeight: 400, overflowY: 'auto' }}>
          <Row gutter={[16, 16]}>
            {columns.map(column => (
              <Col span={12} key={column.key}>
                <div style={{
                  display: 'flex',
                  alignItems: 'center',
                  padding: '12px',
                  background: '#fafafa',
                  border: '1px solid #f0f0f0',
                  borderRadius: '6px',
                  cursor: 'pointer'
                }}
                onClick={() => {
                  const currentVisible = state.visibleColumns.includes(column.key);
                  const newVisible = currentVisible
                    ? state.visibleColumns.filter(k => k !== column.key)
                    : [...state.visibleColumns, column.key];
                  handleColumnSettings(newVisible);
                }}
                >
                  <Switch
                    checked={state.visibleColumns.includes(column.key)}
                    onChange={() => {
                      const currentVisible = state.visibleColumns.includes(column.key);
                      const newVisible = currentVisible
                        ? state.visibleColumns.filter(k => k !== column.key)
                        : [...state.visibleColumns, column.key];
                      handleColumnSettings(newVisible);
                    }}
                    size="small"
                    style={{ marginRight: 12 }}
                  />
                  <div style={{ flex: 1 }}>
                    <div style={{
                      fontSize: '14px',
                      fontWeight: 500,
                      color: '#262626',
                      marginBottom: column.description ? '4px' : 0
                    }}>
                      {column.title}
                    </div>
                    {column.description && (
                      <div style={{
                        fontSize: '12px',
                        color: '#8c8c8c'
                      }}>
                        {column.description}
                      </div>
                    )}
                  </div>
                </div>
              </Col>
            ))}
          </Row>
        </div>
      </Modal>
    );
  };

  const processedColumns = useMemo(() => {
    const actionColumn = {
      key: 'actions',
      title: '操作',
      width: 150,
      fixed: 'right',
      align: 'center',
      render: (_: unknown, record: T) => {
        const visibleActions = nodeActions.filter(action =>
          action.visible ? action.visible(record) : true
        );

        if (visibleActions.length === 0) return null;

        return (
          <Space size="small">
            {visibleActions.map(action => (
              <Button
                key={action.key}
                type="text"
                size="small"
                icon={action.icon}
                danger={action.danger}
                disabled={action.disabled}
                onClick={() => action.onClick(record)}
              >
                {action.label}
              </Button>
            ))}
          </Space>
        );
      },
    };

    const expandColumn = showExpandColumn ? [{
        key: 'expand',
        title: '',
        width: 50,
        fixed: 'left',
        align: 'center',
        render: (_: unknown, record: T) => {
          const hasChildren = (record as Record<string, any>).hasChildren;
          const recordId = (record as Record<string, any>).id;
          // 使用松散比较确保类型兼容
          const isExpanded = expandedRowKeys.some(key => String(key) === String(recordId));

          if (!hasChildren) {
            return <div style={{ width: 24 }} />;
          }

          return (
            <Button
              type="text"
              size="small"
              icon={isExpanded ? <CaretDownOutlined /> : <CaretRightOutlined />}
              onClick={() => handleExpand(!isExpanded, record)}
            />
          );
        },
      }] : [];

    return [
      ...expandColumn,
      ...columns
        .filter(column => !column.hidden && state.visibleColumns.includes(column.key))
        .map(column => {
          const newColumn = { ...column };

          if (state.pinnedColumns.left?.includes(column.key)) {
            newColumn.fixed = 'left';
          } else if (state.pinnedColumns.right?.includes(column.key)) {
            newColumn.fixed = 'right';
          } else {
            newColumn.fixed = column.fixed;
          }

          if (column.sorter) {
            const sorterInfo = state.sortedInfo as Record<string, any>;
            newColumn.sortOrder = sorterInfo?.field === column.dataIndex ? sorterInfo?.order : null;
          }

          if (column.filters) {
            const filteredInfo = state.filteredInfo as Record<string, any>;
            newColumn.filteredValue = filteredInfo?.[column.dataIndex] || null;
          }

          if (column.render) {
            const originalRender = column.render;
            newColumn.render = (value: unknown, record: T, index: number) => {
              const level = (record as Record<string, any>).level || 0;
              return originalRender(value, record, index, level);
            };
          }

          return newColumn;
        }),
      nodeActions.length > 0 ? actionColumn : null,
    ].filter(Boolean);
  }, [columns, state.visibleColumns, state.sortedInfo, state.filteredInfo, state.pinnedColumns, nodeActions, expandedRowKeys, showExpandColumn]);  // 使用合并后的 expandedRowKeys

  const processedPagination = pagination === false ? false : {
    current: pagination?.current || 1,
    pageSize: pagination?.pageSize || 10,
    total: pagination?.total || flattenedData.length,
    showSizeChanger: true,
    showQuickJumper: true,
    showTotal: (total: number, range: [number, number]) => `显示 ${range[0]}-${range[1]} 条，共 ${total} 条`,
    pageSizeOptions: ['10', '20', '50', '100'],
  };

  const tableScroll = useMemo(() => {
    if (scroll) {
      return {
        ...scroll,
        x: scroll.x || 1200,
        scrollToFirstRowOnChange: false,
      };
    }
    return {
      x: 1200,
      scrollToFirstRowOnChange: false,
    };
  }, [scroll]);

  const getRowClassName = (record: T, index: number) => {
    const level = (record as Record<string, any>).level || 0;
    let className = '';

    if (rowClassName) {
      className += ` ${rowClassName(record, index, level)}`;
    }

    return className;
  };

  const getOnRow = (record: T, index?: number) => {
    const level = (record as Record<string, any>).level || 0;
    const rowProps = onRow ? onRow(record, index, level) : {};

    return {
      ...rowProps,
      style: {
        ...(rowProps?.style || {}),
      },
    } as React.HTMLAttributes<any>;
  };

  return (
    <>
      <div style={{
        backgroundColor: '#ffffff',
        borderRadius: '6px',
        boxShadow: '0 1px 2px -2px rgba(0, 0, 0, 0.16), 0 3px 6px 0 rgba(0, 0, 0, 0.12), 0 5px 12px 4px rgba(0, 0, 0, 0.09)',
        border: '1px solid #f0f0f0'
      }}>
        <Table<T>
          columns={processedColumns}
          dataSource={flattenedData}
          loading={loading}
          rowKey={rowKey}
          pagination={processedPagination}
          bordered={false}
          size={size}
          showHeader={showHeader}
          scroll={tableScroll}
          title={renderToolbar}
          footer={footer}
          rowClassName={getRowClassName}
          onRow={getOnRow as any}
          onChange={handleTableChange}
          preserveScrollPosition={true}
          virtual={false}
        />
      </div>

      {renderColumnSettings()}
    </>
  );
};

export default TreeTable;